package http
import java.util.concurrent.TimeUnit

import okhttp3._

import scala.util.Try

sealed trait HttpMethod
case object GET extends HttpMethod
case object POST extends HttpMethod

case class Http(url: String, method:HttpMethod = GET,
                data:Array[Byte] = Array.empty,
                headers:Map[String, String] = Map.empty,
                client: OkHttpClient = Http.client) {
    def get(): Try[HttpResponse] = {
        request(GET)
    }
    def post(): Try[HttpResponse] = {
        request(POST)
    }
    private def request(method:HttpMethod): Try[HttpResponse] = {
        val req = method match {
            case GET => new Request.Builder().url(url).get()
            case POST =>
                val contentType:String = headers.get("Content-Type").getOrElse("application/json")
                val mediaType = MediaType.parse(contentType)
                val body = RequestBody.create(mediaType, data)
                new Request.Builder().url(url).post(body)
        }
        headers.foreach(kv => req.addHeader(kv._1, kv._2))
        Try(client.newCall(req.build()).execute())
          .map(resp =>
            HttpResponse(resp.code(), resp.body().bytes(), toMap(resp.headers()))
          )
    }

    private def toMap(headers: Headers):Map[String, String] = {
        var map = Map.empty[String, String]
        val iterator = headers.iterator()
        while (iterator.hasNext){
            val pair = iterator.next()
            map = map + (pair.getFirst() -> pair.getFirst())
        }
        map
    }
}
object Http{

    private val client = createClient()
    private def createClient() = {
        val builder = new okhttp3.OkHttpClient.Builder()
        builder.connectTimeout(10, TimeUnit.SECONDS)
        builder.readTimeout(10, TimeUnit.SECONDS)
        builder.writeTimeout(10, TimeUnit.SECONDS)
        builder.retryOnConnectionFailure(true)
        builder.followRedirects(true)

        val dispatcher = new Dispatcher()
        dispatcher.setMaxRequests(10)
        dispatcher.setMaxRequestsPerHost(10)
        builder.dispatcher(dispatcher)
        builder.build()
    }
}